<?php

/**
 * @desc Backend filter structure. Define active menu-item. 
 *
 */
class Backend_Filter_Structure extends Kernel_Filter 
{
    
    /**
    * Name of system language
    */
    const LANG_SYSTEM = 'lang';
    
    /**
    * Name of the backend interface language
    */
    const LANG_INTERFACE = 'interface_lang';

    /**
     * @desc Names of the through-GET-params. 
     *
     * @var array
     */
    static private $__params = array(
        self::LANG_SYSTEM => null,
        'section' => null,
        'module' => null,
        'manager' => null,
    );

    /**
     * @desc Get values of the through-params. 
     *
     * @param   mixed  $params
     * @return  mixed
     */
    static public function get($params = array()) 
    {
        if (empty($params)) {
            return self::$__params;
        }
        
        $values = array();
        foreach ((array)$params as $param) {
            $values[$param] = self::_get($param);
        }
        return count($values) > 1 ? $values : current($values);
    }
    
    /**
     * Get value of the through-param. 
     *
     * @param   string  $params
     * @return  mixed
     */
    static private function _get($param) 
    {
        return get_array_element(self::$__params, 
            $param, Application::getRequest()->get($param));
    }

    /**
     * Set value of through-param. 
     *
     * @param   string  $param
     * @param   mixed   $value
     */
    static public function set($param, $value) 
    {
        self::$__params[$param] = $value;
    }

    /**
     * Get names of the through-params. 
     * :KLUDGE: надо убрать куда-то, т.к. используется только для менеджеров.
     *
     * @return  array
     */
    static public function params() 
    {
        return array_keys(self::$__params);
    }
    
    /**
     * Backend sections. 
     *
     * @var array
     */
    public static $sections = array();

    /**
     * Current section managers. 
     *
     * @var array
     */
    public static $managers = array();

    /**
     * Start filter. 
     *
     */
    public function process() 
    {
        // language site versions
        $this->_setSystemLang();
        // set backend language interface 
        $this->_setInterfaceLang();
        // after langs are set import backend terms
        Kernel_i18n::import('Backend');
        
        
        parent::process();
        
        $request = Application::getRequest();
        
        // load backend sections
        self::$sections = $this->_getSections();
        // set active section ID
        self::set('section', $request->get('section', key(self::$sections)));
        // check whether selected sections exists
        if (!array_key_exists(self::get('section'), self::$sections)) {
            $this->_abort('Section not found');
        }
        
        // load backend managers according current section
        self::$managers = $this->_getManagers();
        // check whether managers are present in current section
        if (empty(self::$managers)) {
            $this->_abort('Section is empty');
        }
        $module = $request->get('module');
        $manager = $request->get('manager');
        // id manager is not defined then set first from the list
        if (empty($module) && empty($manager)) {
            list($module, $manager) = current(self::$managers);
        // check whether a manager is present in the current section
        } elseif (false === array_search(array($module, $manager), self::$managers)) {
            $this->_abort('Manager not found in section');
        }
        self::set('module', $module);
        self::set('manager', $manager);
    }
    
    /**
    * @desc Callback method as only the current strucuture knows how to behaviour 
    * right. 
    * 
    */
    public function location($lang) 
    {
        $this->_location(array(self::LANG_SYSTEM => $lang));
    }
    
    /**
     * @desc Return default section ID. 
     *
     * @return  integer
     */
    private function _getSections() 
    {
        $query = 'SELECT
                         `id`, `name`
                    FROM
                         `backend_section` 
                   WHERE 
                         `permissions` & ' . $this->getPermission() . '  
                ORDER BY
                         `position`';
        return database::fetchPairs($query);
    }

    /**
     * @desc Get component name for requested action handling. 
     *
     * @return  string
     */
    private function _getManagers() 
    {
        $query = 'SELECT
                         `module`,
                         `name`
                    FROM
                         `backend_manager`
                   WHERE
                         `section_id` = ' . (int)self::get('section') . ' 
                     AND 
                         `permissions` & ' . $this->getPermission() . ' 
                ORDER BY
                         `position`';
        return array_map('array_values', database::fetchAll($query));
    }
    
    /**
    * Возвращает целочисленное представление битовой маски
    * 
    */
    private function getPermission() 
    {
        return pow(2, Backend_Utils_User::getRole(Security_Session::getSubjectId()));
    }
    
    /**
    * Set language site version.
    * 
    */
    private function _setSystemLang() 
    {
        self::set(self::LANG_SYSTEM, Application::getRequest()->get(self::LANG_SYSTEM));
        // control system language if it's necessary 
        $this->_forward(new Kernel_i18n_Structure(array(
            'callback' => array(&$this, 'location')), self::get(self::LANG_SYSTEM)
            ));
    }
    
    /**
    * Set interface language if it's needed.
    * 
    */
    private function _setInterfaceLang() 
    {
        if ($langs = Kernel_i18n_Structure::getBackendInterfaceLang()) {
            $request = Application::getRequest();
            if (!$request->get((self::LANG_INTERFACE))) {
                $this->_location(array(self::LANG_INTERFACE => $langs[0]['code']), true);
            }
            self::set(self::LANG_INTERFACE, $request->get((self::LANG_INTERFACE)));
        }
    }
    
}
